From: Isaku Yamahata Date: Fri, 17 Oct 2008 08:40:15 +0000 (+0900) Subject: [IA64] Change ioports_permit_access interface(). X-Git-Tag: archive/raspbian/4.8.0-1+rpi1~1^2~14070 X-Git-Url: https://dgit.raspbian.org/%22http://www.example.com/cgi/success//%22http:/www.example.com/cgi/success/?a=commitdiff_plain;h=062a542721766eddce45be0756b57f47bf469945;p=xen.git [IA64] Change ioports_permit_access interface(). use VTD to assing device, guest port may not be equal to host port. Change ioports_permit_access interface to get guest pseudo physical address. Signed-off-by: Anthony Xu --- diff --git a/xen/arch/ia64/xen/dom0_ops.c b/xen/arch/ia64/xen/dom0_ops.c index b21cb42e70..341e98af77 100644 --- a/xen/arch/ia64/xen/dom0_ops.c +++ b/xen/arch/ia64/xen/dom0_ops.c @@ -203,7 +203,7 @@ long arch_do_domctl(xen_domctl_t *op, XEN_GUEST_HANDLE(xen_domctl_t) u_domctl) ret = 0; else { if (op->u.ioport_permission.allow_access) - ret = ioports_permit_access(d, fp, lp); + ret = ioports_permit_access(d, fp, fp, lp); else ret = ioports_deny_access(d, fp, lp); } @@ -522,7 +522,7 @@ dom0vp_add_io_space(struct domain *d, unsigned long phys_base, fp = space_number << IO_SPACE_BITS; lp = fp | 0xffff; - return ioports_permit_access(d, fp, lp); + return ioports_permit_access(d, fp, fp, lp); } unsigned long diff --git a/xen/arch/ia64/xen/domain.c b/xen/arch/ia64/xen/domain.c index ade43c0a4e..e1c07bfd6b 100644 --- a/xen/arch/ia64/xen/domain.c +++ b/xen/arch/ia64/xen/domain.c @@ -1993,7 +1993,7 @@ static void __init physdev_init_dom0(struct domain *d) BUG(); if (irqs_permit_access(d, 0, NR_IRQS-1)) BUG(); - if (ioports_permit_access(d, 0, 0xffff)) + if (ioports_permit_access(d, 0, 0, 0xffff)) BUG(); } diff --git a/xen/arch/ia64/xen/mm.c b/xen/arch/ia64/xen/mm.c index 4f18bf7349..d6c2ee5616 100644 --- a/xen/arch/ia64/xen/mm.c +++ b/xen/arch/ia64/xen/mm.c @@ -983,15 +983,22 @@ assign_domain_page(struct domain *d, ASSIGN_writable | ASSIGN_pgc_allocated); } +/* + * Inpurt + * fgp: first guest port + * fmp: first machine port + * lmp: last machine port + */ int -ioports_permit_access(struct domain *d, unsigned int fp, unsigned int lp) +ioports_permit_access(struct domain *d, unsigned int fgp, + unsigned int fmp, unsigned int lmp) { struct io_space *space; - unsigned long mmio_start, mmio_end, mach_start; + unsigned long mmio_start, mach_start, mach_end; int ret; - if (IO_SPACE_NR(fp) >= num_io_spaces) { - dprintk(XENLOG_WARNING, "Unknown I/O Port range 0x%x - 0x%x\n", fp, lp); + if (IO_SPACE_NR(fmp) >= num_io_spaces) { + dprintk(XENLOG_WARNING, "Unknown I/O Port range 0x%x - 0x%x\n", fmp, lmp); return -EFAULT; } @@ -1005,42 +1012,44 @@ ioports_permit_access(struct domain *d, unsigned int fp, unsigned int lp) * I/O port spaces and thus will number port spaces differently. * This is ok, they don't make use of this interface. */ - ret = rangeset_add_range(d->arch.ioport_caps, fp, lp); + ret = rangeset_add_range(d->arch.ioport_caps, fmp, lmp); if (ret != 0) return ret; - space = &io_space[IO_SPACE_NR(fp)]; + space = &io_space[IO_SPACE_NR(fmp)]; /* Legacy I/O on dom0 is already setup */ if (d == dom0 && space == &io_space[0]) return 0; - fp = IO_SPACE_PORT(fp); - lp = IO_SPACE_PORT(lp); + fmp = IO_SPACE_PORT(fmp); + lmp = IO_SPACE_PORT(lmp); if (space->sparse) { - mmio_start = IO_SPACE_SPARSE_ENCODING(fp) & PAGE_MASK; - mmio_end = PAGE_ALIGN(IO_SPACE_SPARSE_ENCODING(lp)); + mach_start = IO_SPACE_SPARSE_ENCODING(fmp) & PAGE_MASK; + mach_end = PAGE_ALIGN(IO_SPACE_SPARSE_ENCODING(lmp)); } else { - mmio_start = fp & PAGE_MASK; - mmio_end = PAGE_ALIGN(lp); + mach_start = fmp & PAGE_MASK; + mach_end = PAGE_ALIGN(lmp); } /* * The "machine first port" is not necessarily identity mapped * to the guest first port. At least for the legacy range. */ - mach_start = mmio_start | __pa(space->mmio_base); + mach_start = mach_start | __pa(space->mmio_base); + mach_end = mach_end | __pa(space->mmio_base); - if (space == &io_space[0]) { + mmio_start = IO_SPACE_SPARSE_ENCODING(fgp) & PAGE_MASK; + + if (VMX_DOMAIN(d->vcpu[0])) + mmio_start |= LEGACY_IO_START; + else if (space == &io_space[0]) mmio_start |= IO_PORTS_PADDR; - mmio_end |= IO_PORTS_PADDR; - } else { + else mmio_start |= __pa(space->mmio_base); - mmio_end |= __pa(space->mmio_base); - } - while (mmio_start <= mmio_end) { + while (mach_start < mach_end) { (void)__assign_domain_page(d, mmio_start, mach_start, ASSIGN_nocache); mmio_start += PAGE_SIZE; mach_start += PAGE_SIZE; @@ -1089,7 +1098,9 @@ ioports_deny_access(struct domain *d, unsigned int fp, unsigned int lp) mmio_end = PAGE_ALIGN(lp_base); } - if (space == &io_space[0] && d != dom0) + if (VMX_DOMAIN(d->vcpu[0])) + mmio_base = LEGACY_IO_START; + else if (space == &io_space[0] && d != dom0) mmio_base = IO_PORTS_PADDR; else mmio_base = __pa(space->mmio_base); diff --git a/xen/include/asm-ia64/iocap.h b/xen/include/asm-ia64/iocap.h index a90a49f47d..4f140b8476 100644 --- a/xen/include/asm-ia64/iocap.h +++ b/xen/include/asm-ia64/iocap.h @@ -7,7 +7,7 @@ #ifndef __IA64_IOCAP_H__ #define __IA64_IOCAP_H__ -extern int ioports_permit_access(struct domain *d, +extern int ioports_permit_access(struct domain *d, unsigned int gs, unsigned int s, unsigned int e); extern int ioports_deny_access(struct domain *d, unsigned int s, unsigned int e);